package ch07 {
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;

	/**
	 * 选装木马效果
	 */
	[SWF(width=800,height=800,backgroundColor=0xffffff)]
	public class Carousel extends Sprite {
		private var _holder:Sprite;
		private var _items:Array;
		private var _radius:Number = 200;
		private var _numItems:int = 10;

		public function Carousel(){

			/**
			   fieldOfView 属性
			   为三维视野指定一个角度（介于 0 度到 180 度之间）。此值可确定应用于具有非零 z 坐标的三维显示对象的透视转换和扭曲的强度。
			   若角度接近于 0，则表示屏幕的二维 x 和 y 坐标与三维 x、y 和 z 坐标大致相同，只不过具有少许扭曲或无扭曲。换句话说，若角度较小，则沿 z 轴下移的显示对象看起来大小不变且移动距离很小。
			   若值接近于 180 度，则会产生鱼眼镜头效果，即 z 值小于 0 的位置将被放大，而 z 值大于 0 的位置将被最小化。若角度较大，则沿 z 轴下移的显示对象看起来大小变化很快且移动距离很大。如果视野设置为 0 或 180，则屏幕上不会显示任何内容。
			 */
			root.transform.perspectiveProjection.fieldOfView =130;
			//root.transform.perspectiveProjection.focalLength = 100;
			trace("fieldOfView:", root.transform.perspectiveProjection.fieldOfView);
			trace("focalLength:", root.transform.perspectiveProjection.focalLength);
			_holder = new Sprite();
			_holder.x = stage.stageWidth / 2;
			_holder.y = stage.stageHeight / 2;
			_holder.z = 0;
			addChild(_holder);
			_items = [];

			for (var i:int = 0; i < _numItems; i++){
				var angle:Number = Math.PI * 2 / _numItems * i;
				var item:Sprite = makeItem();
				item.x = Math.cos(angle) * _radius;
				item.z = Math.sin(angle) * _radius;
				item.rotationY = -360 / _numItems * i + 90;
				_items.push(item);
			}
			sortItems();

			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		private function makeItem():Sprite {
			var item:Sprite = new Sprite();
			var g:Graphics = item.graphics;
			g.beginFill(Math.random() * 0xffffff);
			g.drawRect(-50, -50, 100, 100);
			g.endFill();
			_holder.addChild(item);
			return item;
		}

		private function sortItems():void {
			_items.sort(depthSort);
			for each (var item:Sprite in _items){
				_holder.addChild(item);
			}
		}

		private function depthSort(objA:DisplayObject, objB:DisplayObject):int {
			var _holderMatrix3D:Matrix3D = _holder.transform.matrix3D;
			var posA:Vector3D = objA.transform.matrix3D.position;
			posA = _holderMatrix3D.deltaTransformVector(posA);
			var posB:Vector3D = objB.transform.matrix3D.position;
			posB = _holderMatrix3D.deltaTransformVector(posB);
			return posB.z - posA.z;
		}

		private function onEnterFrame(event:Event):void {
			_holder.rotationY += (stage.stageWidth / 2 - mouseX) * .01;
			_holder.y += (mouseY - _holder.y) * .1;
			sortItems();
		}
	}
}
